using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
class PrintableForm: Form
{
	public static void Main()
	{
		Application.Run(new PrintableForm());
	}
	public PrintableForm()
	{
		Text = "Printable Form";
		BackColor = SystemColors.Window;
		ForeColor = SystemColors.WindowText;
		ResizeRedraw = true;
	}
	protected override void OnPaint(PaintEventArgs pea)
	{
		DoPage(pea.Graphics, ForeColor,
			ClientSize.Width, ClientSize.Height);
	}
	protected override void OnClick(EventArgs ea)
	{
		PrintDocument prndoc = new PrintDocument();
		prndoc.DocumentName = Text;
		prndoc.PrintPage +=
			new PrintPageEventHandler(PrintDocumentOnPrintPage);
		prndoc.Print();
	}
	void PrintDocumentOnPrintPage(object obj, PrintPageEventArgs ppea)
	{
		Graphics grfx = ppea.Graphics;
		SizeF sizef = grfx.VisibleClipBounds.Size;
		DoPage(grfx, Color.Black, (int)sizef.Width, (int)sizef.Height);
	}
	protected virtual void DoPage(Graphics grfx, Color clr, int cx, int
		cy)
	{
		Pen pen = new Pen(clr);
		grfx.DrawLine(pen, 0, 0, cx - 1, cy - 1);
		grfx.DrawLine(pen, cx - 1, 0, 0, cy - 1);
	}
}
class DotsPerInch: PrintableForm
{
	public new static void Main()
	{
		Application.Run(new DotsPerInch());
	}
	public DotsPerInch()
	{
		Text = "Dots Per Inch";
	}
	protected override void DoPage(Graphics grfx, Color clr, int cx, int
		cy)
	{
//		grfx.DrawString(String.Format("DpiX = {0}\nDpiY = {1}",
//			grfx.DpiX, grfx.DpiY),
//			Font, new SolidBrush(clr), 0, 0);

//		grfx.FillRectangle(new SolidBrush(clr), 100, 100, 100, 100);
		grfx.DrawEllipse(new Pen(clr), 0, 0, grfx.DpiX, grfx.DpiY);
	}
}
class TenCentimeterRuler: PrintableForm
{
	public new static void Main()
	{
		Application.Run(new TenCentimeterRuler());
	}
	public TenCentimeterRuler()
	{
		Text = "Ten-Centimeter Ruler";
	}
	protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
	{
		Pen pen = new Pen(clr);
		Brush brush = new SolidBrush(clr);
		const int xOffset = 10;
		const int yOffset = 10;
		grfx.DrawPolygon(pen, new PointF[]
				{
				MMConv(grfx, new PointF(xOffset, yOffset)),
				MMConv(grfx, new PointF(xOffset + 100, yOffset)),
				MMConv(grfx, new PointF(xOffset + 100, yOffset + 10)),
				MMConv(grfx, new PointF(xOffset, yOffset + 10))
				});
		StringFormat strfmt = new StringFormat();
		strfmt.Alignment = StringAlignment.Center;
		for (int i = 1; i < 100; i++)
		{
			if (i % 10 == 0) // Centimeter markings
			{
				grfx.DrawLine(pen,
					MMConv(grfx, new PointF(xOffset + i, yOffset)),
					MMConv(grfx, new PointF(xOffset + i, yOffset +
					5)));
				grfx.DrawString((i/10).ToString(), Font, brush,
					MMConv(grfx, new PointF(xOffset + i, yOffset +
					5)),
					strfmt);
			}
			else if (i % 5 == 0) // Half-centimeter markings
			{
				grfx.DrawLine(pen,
					MMConv(grfx, new PointF(xOffset + i, yOffset)),
					MMConv(grfx, new PointF(xOffset + i, yOffset +
					3)));
			}
			else // Millimeter markings
			{
				grfx.DrawLine(pen,
					MMConv(grfx, new PointF(xOffset + i, yOffset)),
					MMConv(grfx, new PointF(xOffset + i, yOffset +
					2.5f)));
			}
		}
	}
	PointF MMConv(Graphics grfx, PointF pointf)
	{
		pointf.X *= grfx.DpiX / 25.4f;
		pointf.Y *= grfx.DpiY / 25.4f;
		return pointf;
	}
}